import LXCOM from '../common/common.js'
import absgraph from './absgraph.js'
import { CoordTRFUtil } from '../common/tools/coordtool.js'
import { PositionUtil } from '../common/tools/positionutil.js'
import Coord from '../common/struct/coord.js'
import UtilFuncs from '../common/tools/utilfuncs.js'
var funcs = UtilFuncs.UtilFuncs;

import GlobalConst from '../common/globalConst.js'
var global = GlobalConst.GlobalConst;

import DevGraphInfoPkg from '../common/struct/basestruct/devgraphinfo.js'
var DevGraphInfo = DevGraphInfoPkg.DevGraphInfo;

import { LGXEnums } from '../common/sysenum.js'


class LGXLineSec {
    constructor() {
        this.stpoint = new LXCOM.LGXPoint();
        this.endpoint = new LXCOM.LGXPoint();
        this.lineDef = new LXCOM.LGXLineDefInfo();
    }
}

class DeviceGraph extends absgraph.AbsGraph {
    constructor(type) {
        super(type);
        var pos = new Coord.PointPos();
        this.setPos(pos);
        this.m_graphType = LGXEnums.LGXGraphType.MoldGraph_type;
        this.labelCtrlFlag = 0;
        this.refSymbolUUID = '';
    }

    act2Mouse(mosEvnt, worldPos) {
        var position = this.getPos();
        if (mosEvnt.type == LGXEnums.LGXMouseMode.LMouseDown) {
            position.x = worldPos.x;
            position.y = worldPos.y;
            this.setStart(1);
            this.setFinish(1);
            this.calScope(1);
        }
    }

    display(map, mapInfo, forClip) {
        var position = this.getPosCopy();
        map.save();
        var symbol = this.getSymbol();
        if (symbol != null && !symbol.getMoldActionType() > LGXEnums.moldActionType.common) {
            // console.log("block dis*****************************start");
            // let tt = new absgraph.LineUnitCounter();
            // tt.lineUnitCount = 0;
            let scalex = this.getScaleX();
            let scaley = this.getScaleY();
            let rotv = this.getRadAngle();
            let transformInfo = new absgraph.TransformInfo();
            transformInfo.sx = scalex;
            transformInfo.sy = scaley;
            transformInfo.orinPt.x = position.x;
            transformInfo.orinPt.y = position.y;
            transformInfo.rotRad = rotv;
            // let cntScreenPT = CoordTRFUtil.world2Screen(position,mapInfo);
            // map.translate(cntScreenPT.x, cntScreenPT.y);
            // map.rotate(-rotv);
            // map.scale(this.localScale.x,this.localScale.y);
            // map.translate(-cntScreenPT.x, -cntScreenPT.y);
            symbol.display(this,transformInfo, map, mapInfo, forClip);

            // console.log("block dis ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~end");
        }
        map.restore();
        if (this._selected) {
            this.displayFeaturePoint(map, mapInfo);
        }
        super.displayGraphScope(map, mapInfo);

        // map.beginPath();
        // map.moveTo(0, 0);
        // map.lineTo(tx, ty);
        // map.lineTo(pt1.x, pt1.y);
        // map.stroke();
        // map.closePath();
    }

    disInSymbol(transformInfo, map, mapInfo, forClip) {
        var position = this.getPosCopy();
        map.save();
        var symbol = this.getSymbol();
        if (symbol != null && !symbol.getMoldActionType() > LGXEnums.moldActionType.common) {
            let x = (position.x) * transformInfo.sx;
            let y = (position.y) * transformInfo.sy;
            x += transformInfo.orinPt.x;
            y += transformInfo.orinPt.y;
            let rotPt = funcs.rotate({ x, y }, transformInfo.orinPt, transformInfo.rotRad);

            let childTransformInfo = transformInfo.cloneCopy(transformInfo);
            childTransformInfo.rotate_degree(this._angle);
            childTransformInfo.scale(this.localScale.x, this.localScale.y);
            childTransformInfo.orinPt.x = rotPt.x;
            childTransformInfo.orinPt.y = rotPt.y;

            // let rotv = this.getRadAngle();
            // let cntScreenPT = CoordTRFUtil.local2Screen(position,mapInfo);
            // map.translate(cntScreenPT.x, cntScreenPT.y);
            // map.rotate(-rotv);
            // map.scale(this.localScale.x,this.localScale.y);
            // map.translate(-cntScreenPT.x, -cntScreenPT.y);
            symbol.display(this,childTransformInfo, map, mapInfo, forClip);
        }
        map.restore();
    }
    displayFeaturePoint(map, mapInfo) {
        super.displayFeaturePoint(map, mapInfo);
    }

    assignInfo(info) {
        super.initCommProp(info);
        var position = this.getPos();
        this.m_gid = info.gid;
        this.type = info.type;
        position.x = info.x;
        position.y = info.y;
        this.setScaleX(info.scalex);
        this.setScaleY(info.scaley);
        this.setAngle(info.angle);
        this.refSymbolUUID = info.refSymbolUUID;
    }

    modifyAttribute(obj, mapscale) {
        var position = this.getPos();
        position.x = obj.x;
        position.y = obj.y;
        this.setAngle(obj.angle);
        this.setUseful(obj.m_nUseful);
        if (this.getNewAdd() == 0 && obj.m_nNewAdd != 0) {
            this.setNewAdd(obj.m_nNewAdd);
        }
    }


    calScope(mapscale) {
        var position = this.getPos();
        // let rect = this.calculateZone(position, this.getRadAngle());
        let ptlist = this.getScopeVertexPtLst(1);
        this._zone.clone(funcs.calPtListZone(ptlist));
    }

    getLocalOrigin() {
        var position = this.getPos();
        return { x: position.x, y: position.y };
    }
    getLocalZone() {
        var position = this.getPos();
        let rect = this.calculateZone(position);
        rect.left -= position.x;
        rect.bottom -= position.y;
        rect.right -= position.x;
        rect.top -= position.y;
        return rect;
    }

    calculateZone(devPos) {
        let rect = null;
        var symbol = this.getSymbol();
        if (symbol != null) {
            if (symbol.getMoldActionType() == LGXEnums.moldActionType.container) {
                if (this.getChildList().length == 0) {
                    rect = this.calculateZoneRefSymbol(devPos, symbol);
                }
                else {
                    rect = this.calculateZoneEncloseAllChilds();
                }
            }
            else {
                rect = this.calculateZoneRefSymbol(devPos, symbol);
            }
        }
        else {
            rect = new LXCOM.LGXRect(0, 0, 0, 0);
            var offsetGap = 5;
            rect.left = (devPos.x - offsetGap);
            rect.bottom = (devPos.y - offsetGap);
            rect.right = (devPos.x + offsetGap);
            rect.top = (devPos.y + offsetGap);
        }
        return rect;
    }

    reCalScopeEncloseAllChild(mapscale) {
        let rect = this.calculateZoneEncloseAllChilds();
        this._zone.clone(rect);
        let cntPt = rect.getCnt();
        let newPos = new Coord.PointPos();
        newPos.x = cntPt.x;
        newPos.y = cntPt.y;
        this.setPos(newPos);
    }

    calculateZoneEncloseAllChilds() {
        let initFlag = false;
        let rect = new LXCOM.LGXRect(0, 0, 0, 0);
        let childList = this.getAllChild();
        for (let i = 0; i < childList.length; i++) {
            let child = childList[i];
            if (child == this) {
                continue;
            }
            if (child.m_graphType == LGXEnums.LGXGraphType.TextGraph_type) {
                continue;
            }
            let childZone = child.getZone();
            if (!initFlag) {
                rect.clone(childZone);
                initFlag = true;
            }

            let x = childZone.left;
            let y = childZone.top;
            var p1 = { x, y };

            x = childZone.right;
            y = childZone.bottom;
            var p2 = { x, y };

            rect.left = Math.min(rect.left, p1.x);
            rect.right = Math.max(rect.right, p1.x);
            rect.left = Math.min(rect.left, p2.x);
            rect.right = Math.max(rect.right, p2.x);

            rect.bottom = Math.min(rect.bottom, p1.y);
            rect.top = Math.max(rect.top, p1.y);
            rect.bottom = Math.min(rect.bottom, p2.y);
            rect.top = Math.max(rect.top, p2.y);
        }
        return rect;
    }

    calculateZoneRefSymbol(devPos, symbol) {
        if (!symbol) {
            return;
        }
        let rect = new LXCOM.LGXRect(0, 0, 0, 0);
        var symScope = symbol.getSymScope();
        let x = symScope.left * this.getScaleX();
        let y = symScope.top * this.getScaleY();
        var p1 = { x, y };

        x = symScope.right * this.getScaleX();
        y = symScope.top * this.getScaleY();
        var p2 = { x, y };

        x = symScope.right * this.getScaleX();
        y = symScope.bottom * this.getScaleY();
        var p3 = { x, y };

        x = symScope.left * this.getScaleX();
        y = symScope.bottom * this.getScaleY();
        var p4 = { x, y };

        var minx = Math.min(p1.x, p2.x);
        minx = Math.min(minx, p3.x);
        minx = Math.min(minx, p4.x);

        var maxx = Math.max(p1.x, p2.x);
        maxx = Math.max(maxx, p3.x);
        maxx = Math.max(maxx, p4.x);

        var miny = Math.min(p1.y, p2.y);
        miny = Math.min(miny, p3.y);
        miny = Math.min(miny, p4.y);

        var maxy = Math.max(p1.y, p2.y);
        maxy = Math.max(maxy, p3.y);
        maxy = Math.max(maxy, p4.y);

        rect.left = minx;
        rect.bottom = miny;
        rect.right = maxx;
        rect.top = maxy;

        rect.left += devPos.x;
        rect.bottom += devPos.y;
        rect.right += devPos.x;
        rect.top += devPos.y;

        return rect;
    }

    distance(tPos, scaling, mapscale) {
        var dis = -1;
        if (this.getStart() == 1 && this.getFinish() == 1) {
            if (super.preCheckInScope(tPos, scaling)) {
                dis = 0;
            }
        }
        return dis;
    }

    calculateSubKind(mousePt, scaling, mapscale) {
        let selKind = 0;
        var ptlst = this.getScopeVertexPtLst(scaling);
        var count = ptlst.length;
        for (var i = 0; i < count; i++) {
            var pt = ptlst[i];
            var dis = funcs.distancePoint(mousePt, pt, scaling);
            if (dis < global.SelectGap) {
                selKind = i + 1;
                console.log("kind=" + i);
                break;
            }
        }
        if (selKind == 0) {
            if (this.getStart() == 1 && this.getFinish() == 1) {
                if (super.preCheckInScope(mousePt, scaling)) {
                    selKind = 5;
                }
            }
        }
        return selKind;
    }

    movePosOffset(offsetPt, modCmdInfo) {
        var vertexPtlst = this.getScopeVertexPtLst(modCmdInfo.scaling);
        console.log("selkind=" + this._selKind);
        console.log("tx=" + offsetPt.x, "ty=" + offsetPt.y);

        var orignalPtlst = this.getScopeVertexPtLst(modCmdInfo.scaling);

        if (this._selKind == 5) {
            this.translate(offsetPt, modCmdInfo.mapscale, false);
        }
        else if (this._selKind == 1
            || this._selKind == 2
            || this._selKind == 3
            || this._selKind == 4) {
            //局部坐标系旋转后，XY轴顶点的为轴，原点仍然是（0，0）
            var rotv = this.getRadAngle();
            var x = 0;
            var y = 0;
            var rotcnt = { x, y };

            //X轴顶点，取（1，0）
            x = 1;
            y = 0;
            var px = { x, y };
            var px1 = funcs.rotate(px, rotcnt, rotv);

            //X轴顶点，取（1，0）
            x = 0;
            y = 1;
            var py = { x, y };
            var py1 = funcs.rotate(py, rotcnt, rotv);

            var xAxis = new LGXLineSec();
            var yAxis = new LGXLineSec();

            xAxis.stpoint.x = 0;
            xAxis.stpoint.y = 0;
            xAxis.endpoint.x = px1.x;
            xAxis.endpoint.y = px1.y;

            yAxis.stpoint.x = 0;
            yAxis.stpoint.y = 0;
            yAxis.endpoint.x = py1.x;
            yAxis.endpoint.y = py1.y;

            //原始位置转为局部坐标
            var orinPt = orignalPtlst[this._selKind - 1];
            x = orinPt.x - this._position.x;
            y = orinPt.y - this._position.y;
            var localPt = { x, y };

            var orignalHalfHgt = funcs.pointToLineDistance(localPt, xAxis.stpoint, xAxis.endpoint);
            var orignalHalfWid = funcs.pointToLineDistance(localPt, yAxis.stpoint, yAxis.endpoint);

            var selPtCurentPos = vertexPtlst[this._selKind - 1];

            selPtCurentPos.x += offsetPt.x;
            selPtCurentPos.y += offsetPt.y;

            //转为局部坐标
            x = selPtCurentPos.x - this._position.x;
            y = selPtCurentPos.y - this._position.y;
            var localPt2 = { x, y };

            //到局部坐标系X轴的距离，就是新的高度
            var dis2xAxsis = funcs.pointToLineDistance(localPt2, xAxis.stpoint, xAxis.endpoint);

            //到局部坐标系Y轴的距离，就是新的宽度
            var dis2yAxsis = funcs.pointToLineDistance(localPt2, yAxis.stpoint, yAxis.endpoint);
            console.log("dis2xAxsis=" + dis2xAxsis, "dis2yAxsis=" + dis2yAxsis);
            var sx = Math.abs(dis2yAxsis) / orignalHalfWid;
            var sy = Math.abs(dis2xAxsis) / orignalHalfHgt;
            this.setScaleX(sx);
            this.setScaleY(sy);
            console.log("sx=" + sx, "sy=" + sy);
        }
    }

    getScopeVertexPtLst1(scaleX, scaleY) {
        var symbol = this.getSymbol();
        if (!symbol) {
            return;
        }
        var position = this.getPos();
        var symScope = symbol.getSymScope();
        var rotv = this.getRadAngle();
        var x = symScope.getCnt().x;
        var y = symScope.getCnt().y;
        var rotcnt = { x, y };
        x = symScope.left * scaleX;
        y = symScope.top * scaleY;
        var lefttopPt = { x, y };
        var p1 = funcs.rotate(lefttopPt, rotcnt, rotv);

        x = symScope.right * scaleX;
        y = symScope.top * scaleY;
        var righttopPt = { x, y };
        var p2 = funcs.rotate(righttopPt, rotcnt, rotv);

        x = symScope.right * scaleX;
        y = symScope.bottom * scaleY;
        var rightbotPt = { x, y };
        var p3 = funcs.rotate(rightbotPt, rotcnt, rotv);

        x = symScope.left * scaleX;
        y = symScope.bottom * scaleY;
        var leftbotPt = { x, y };
        var p4 = funcs.rotate(leftbotPt, rotcnt, rotv);

        //图符中心点
        x = symScope.getCnt().x;
        y = symScope.getCnt().y;
        var shakeHandBotPt = { x, y };
        var p5 = funcs.rotate(shakeHandBotPt, rotcnt, rotv);

        //旋转把手顶点
        x = (symScope.left + symScope.right) * 0.5;
        y = symScope.top * scaleY + 5;
        var shakeHandTopPt = { x, y };
        var p6 = funcs.rotate(shakeHandTopPt, rotcnt, rotv);

        var ptlst = new Array();
        ptlst.push(p1);
        ptlst.push(p2);
        ptlst.push(p3);
        ptlst.push(p4);
        ptlst.push(p5);
        ptlst.push(p6);
        var count = ptlst.length;
        for (var i = 0; i < count; i++) {
            var pt = ptlst[i];
            pt.x += position.x;
            pt.y += position.y;
        }
        return ptlst;
    }


    getPosCopy() {
        let pos = new Coord.PointPos();
        pos.clone(this._position);
        return pos;
    }

    setScaleX(s) { this.localScale.x = s; }
    getScaleX() { return this.localScale.x; }

    setScaleY(s) { this.localScale.y = s; }
    getScaleY() { return this.localScale.y; }

    toInfo() {
        var info = new DevGraphInfo();
        super.commoneProp2Info(info);
        var position = this.getPos();
        info.pos.clone(position);
        info.x = position.x;
        info.y = position.y;
        info.scalex = this.getScaleX();
        info.scaley = this.getScaleY();
        if (this._refSymbol){
            info.refSymbolUUID = this._refSymbol.getUUID();
        }
        return info;
    }

    resetLeadwirePos(prePt, curentPt, mapscale) {
        let x = curentPt.x - prePt.x;
        let y = curentPt.y - prePt.y;
        let offsetPt = { x, y };
        this.m_tChildGraphLst.forEach(child => {
            if (child.m_graphType == LGXEnums.LGXGraphType.LineGraph_type
                && child.getSymbolLeadwireFlag()) {
                child.translate(offsetPt, mapscale, false);
            }
        });
    }

    //设置被选中，并且加入数据管理类选中图形队列中。单选时调用
    setSelect(v) {
        this._selected = v;
        this.notifySelectToObserver(v);
        this.m_tChildGraphLst.forEach(child => {
            if (child.m_graphType == LGXEnums.LGXGraphType.LineGraph_type
                && child.getSymbolLeadwireFlag()) {
                child.setSelect(v);
            }
        });
    }


    getFrameRect() {
        let frameRect = null;
        let childList = this.getChildList();
        for (let i = 0; i < childList.length; i++) {
            let child = childList[i];
            if (child.m_graphType == LGXEnums.LGXGraphType.RectGraph_type) {
                if (child.getSymbolEdgeFlag()) {
                    frameRect = child;
                }
            }
        }
        return frameRect;
    }

    getTitleText() {
        let titleText = null;
        for (let i = 0; i < this.m_tChildGraphLst.length; i++) {
            let child = this.m_tChildGraphLst[i];
            if (child.m_graphType == LGXEnums.LGXGraphType.TextGraph_type && child.isTitle()) {
                titleText = child;
                break;
            }
            let label = child.getLabel();
            if (label && label.m_graphType == LGXEnums.LGXGraphType.TextGraph_type && label.isTitle()) {
                titleText = label;
                break;
            }
        }
        return titleText;
    }

    getTitleZoneRect() {
        let titleZoneRect = null;
        let childList = this.getChildList();
        for (let i = 0; i < childList.length; i++) {
            let child = childList[i];
            if (child.m_graphType == LGXEnums.LGXGraphType.RectGraph_type) {
                if (child.getTitleZoneFlag()) {
                    titleZoneRect = child;
                }
            }
        }
        return titleZoneRect;
    }

    getMainFeaturePTLst(tFeaturePTLst, transformInfo) {
        var symbol = this.getSymbol();
        if (symbol) {
            let nextTransform = this.getNextTransform(transformInfo);
            symbol.getMainFeaturePTLst(tFeaturePTLst, nextTransform);
        }
    }

    getSubFeaturePTLst(tFeaturePTLst, mousePoint, transformInfo) {
        var symbol = this.getSymbol();
        if (symbol) {
            let nextTransform = this.getNextTransform(transformInfo);
            symbol.getSubFeaturePTLst(tFeaturePTLst, mousePoint, nextTransform);
        }
    }

    getNextTransform(transformInfo) {
        let nextTransform = null;
        let position = this.getPosCopy();
        if (!transformInfo) {
            nextTransform = new absgraph.TransformInfo();
            nextTransform.sx = this.localScale.x;
            nextTransform.sy = this.localScale.y;
            nextTransform.orinPt.x = position.x;
            nextTransform.orinPt.y = position.y;
            nextTransform.rotRad = this.getRadAngle();
        }
        else {
            let x = (position.x) * transformInfo.sx;
            let y = (position.y) * transformInfo.sy;
            x += transformInfo.orinPt.x;
            y += transformInfo.orinPt.y;
            let rotPt = funcs.rotate({ x, y }, transformInfo.orinPt, transformInfo.rotRad);
            nextTransform = transformInfo.cloneCopy(transformInfo);
            nextTransform.rotate_degree(this._angle);
            nextTransform.scale(this.localScale.x, this.localScale.y);
            nextTransform.orinPt.x = rotPt.x;
            nextTransform.orinPt.y = rotPt.y;
        }

        return nextTransform;
    }

    //复制粘贴时，从复制源对象复制属性到本图形对应属性----虚函数，由实体继承类实现
    copySubPropFromBuf(bufInfo,tx,ty){
        this.scale(bufInfo.scalex,bufInfo.scaley);
    }
}

export default { DeviceGraph }
